import {Buffer} from "buffer";
import {AxdrNull} from "../asn1.axdr/AxdrNull";
import {Selector2} from "./Selector2";
import {Selector1} from "./Selector1";
import {Selector3} from "./Selector3";
import {Selector4} from "./Selector4";
import {Selector5} from "./Selector5";
import {Selector6} from "./Selector6";
import {Selector7} from "./Selector7";
import {Selector8} from "./Selector8";
import {Selector9} from "./Selector9";
import {Selector10} from "./Selector10";
import {AxdrType} from "../asn1.axdr/AxdrType";
import {ReverseByteArrayInputStream} from "../ReverseByteArrayInputStream";
import {ReverseByteArrayOutputStream} from "../ReverseByteArrayOutputStream";
import {AxdrEnum} from "../asn1.axdr/AxdrEnum";


enum Choice {

    _ERR_NONE_SELECTED = -1,
    OMD0 = 0,
    S1 = 1,
    S2 = 2,
    S3 = 3,
    S4 = 4,
    S5 = 5,
    S6 = 6,
    S7 = 7,
    S8 = 8,
    S9 = 9,
    S10 = 10

}

export class RSD implements AxdrType{

    dataCode : Buffer | null = null;
    choice: Choice = Choice._ERR_NONE_SELECTED;
    omd0 : AxdrNull | null = null;
    s1 : Selector1 | null = null;
    s2 : Selector2 | null = null;
    s3 : Selector3 | null = null;
    s4 : Selector4 | null = null;
    s5 : Selector5 | null = null;
    s6 : Selector6 | null = null;
    s7 : Selector7 | null = null;
    s8 : Selector8 | null = null;
    s9 : Selector9 | null = null;
    s10 : Selector10 | null = null;

    constructor() {
    }

    set_dataCode(dataCode : Buffer){
        this.dataCode = dataCode;
    }


    decode(input: ReverseByteArrayInputStream): number {
        let codeLength = 0;
        let choosen = new AxdrEnum();
        choosen.set_const();

        codeLength += choosen.decode(input);
        this.resetChoices();
        this.choice = choosen.getValue();

        if (this.choice == Choice.OMD0) {
            this.omd0 = new AxdrNull();
            codeLength += this.omd0.decode(input);
            return codeLength;
        }

        if (this.choice == Choice.S1) {
            this.s1 = new Selector1();
            codeLength += this.s1.decode(input);
            return codeLength;
        }

        if (this.choice == Choice.S2) {
            this.s2 = new Selector2();
            codeLength += this.s2.decode(input);
            return codeLength;
        }

        if (this.choice == Choice.S3) {
            this.s3 = new Selector3();
            codeLength += this.s3.decode(input);
            return codeLength;
        }

        if (this.choice == Choice.S4) {
            this.s4 = new Selector4();
            codeLength += this.s4.decode(input);
            return codeLength;
        }

        if (this.choice == Choice.S5) {
            this.s5 = new Selector5();
            codeLength += this.s5.decode(input);
            return codeLength;
        }

        if (this.choice == Choice.S6) {
            this.s6 = new Selector6();
            codeLength += this.s6.decode(input);
            return codeLength;
        }

        if (this.choice == Choice.S7) {
            this.s7 = new Selector7();
            codeLength += this.s7.decode(input);
            return codeLength;
        }

        if (this.choice == Choice.S8) {
            this.s8 = new Selector8();
            codeLength += this.s8.decode(input);
            return codeLength;
        }

        if (this.choice == Choice.S9) {
            this.s9 = new Selector9();
            codeLength += this.s9.decode(input);
            return codeLength;
        }

        if (this.choice == Choice.S10) {
            this.s10 = new Selector10();
            codeLength += this.s10.decode(input);
            return codeLength;
        }

        throw new Error("Error decoding AxdrChoice: Identifier matched to no item.");
    }

    encode(output: ReverseByteArrayOutputStream): number {

        if (this.dataCode != null) {
            for (let i = this.dataCode.length - 1; i >= 0; i--) {
                output.write(this.dataCode[i]);
            }
            return this.dataCode.length;

        }
        if (this.choice == Choice._ERR_NONE_SELECTED) {
            throw new Error("Error encoding AxdrChoice: No item in choice was selected.");
        }

        let codeLength = 0;

        if (this.choice == Choice.S10) {
            codeLength += this.s10.encode(output);
            let c = new AxdrEnum();
            c.set_min_max_val(10);
            codeLength += c.encode(output);
            return codeLength;
        }

        if (this.choice == Choice.S9) {
            codeLength += this.s9.encode(output);
            let c = new AxdrEnum();
            c.set_min_max_val(9);
            codeLength += c.encode(output);
            return codeLength;
        }

        if (this.choice == Choice.S8) {
            codeLength += this.s8.encode(output);
            let c = new AxdrEnum();
            c.set_min_max_val(8);
            codeLength += c.encode(output);
            return codeLength;
        }

        if (this.choice == Choice.S7) {
            codeLength += this.s7.encode(output);
            let c = new AxdrEnum();
            c.set_min_max_val(7);
            codeLength += c.encode(output);
            return codeLength;
        }

        if (this.choice == Choice.S6) {
            codeLength += this.s6.encode(output);
            let c = new AxdrEnum();
            c.set_min_max_val(6);
            codeLength += c.encode(output);
            return codeLength;
        }

        if (this.choice == Choice.S5) {
            codeLength += this.s5.encode(output);
            let c = new AxdrEnum();
            c.set_min_max_val(5);
            codeLength += c.encode(output);
            return codeLength;
        }

        if (this.choice == Choice.S4) {
            codeLength += this.s4.encode(output);
            let c = new AxdrEnum();
            c.set_min_max_val(4);
            codeLength += c.encode(output);
            return codeLength;
        }

        if (this.choice == Choice.S3) {
            codeLength += this.s3.encode(output);
            let c = new AxdrEnum();
            c.set_min_max_val(3);
            codeLength += c.encode(output);
            return codeLength;
        }

        if (this.choice == Choice.S2) {
            codeLength += this.s2.encode(output);
            let c = new AxdrEnum();
            c.set_min_max_val(2);
            codeLength += c.encode(output);
            return codeLength;
        }

        if (this.choice == Choice.S1) {
            codeLength += this.s1.encode(output);
            let c = new AxdrEnum();
            c.set_min_max_val(1);
            codeLength += c.encode(output);
            return codeLength;
        }

        if (this.choice == Choice.OMD0) {
            codeLength += this.omd0.encode(output);
            let c = new AxdrEnum();
            c.set_min_max_val(0);
            codeLength += c.encode(output);
            return codeLength;
        }

        throw new Error("Error encoding AxdrChoice: No item in choice was encoded.");
    }

    resetChoices(){
        this.choice = Choice._ERR_NONE_SELECTED;
        this.omd0 = null;
        this.s1 = null;
        this.s2 = null;
        this.s3 = null;
        this.s4 = null;
        this.s5 = null;
        this.s6 = null;
        this.s7 = null;
        this.s8 = null;
        this.s9 = null;
        this.s10 = null;
    }

    encodeAndSave(encodingSizeGuess: number) {
        let revOStream = new ReverseByteArrayOutputStream();
        revOStream.setBufSize(encodingSizeGuess);
        this.encode(revOStream);
        this.dataCode = revOStream.getArray();
    }

    getChoiceIndex(): Choice {
        return this.choice;
    }

    setOmd0(omd0 : AxdrNull){
        this.resetChoices();
        this.choice = Choice.OMD0;
        this.omd0 = omd0;
    }

    setS1(s1 : Selector1){
        this.resetChoices();
        this.choice = Choice.S1;
        this.s1 = s1;
    }

    setS2(s2 : Selector2){
        this.resetChoices();
        this.choice = Choice.S2;
        this.s2 = s2;
    }

    setS3(s3 : Selector3){
        this.resetChoices();
        this.choice = Choice.S3;
        this.s3 = s3;
    }

    setS4(s4 : Selector4){
        this.resetChoices();
        this.choice = Choice.S4;
        this.s4 = s4;
    }

    setS5(s5 : Selector5){
        this.resetChoices();
        this.choice = Choice.S5;
        this.s5 = s5;
    }

    setS6(s6 : Selector6){
        this.resetChoices();
        this.choice = Choice.S6;
        this.s6 = s6;
    }

    setS7(s7 : Selector7){
        this.resetChoices();
        this.choice = Choice.S7;
        this.s7 = s7;
    }

    setS8(s8 : Selector8){
        this.resetChoices();
        this.choice = Choice.S8;
        this.s8 = s8;
    }

    setS9(s9 : Selector9){
        this.resetChoices();
        this.choice = Choice.S9;
        this.s9 = s9;
    }

    setS10(s10 : Selector10){
        this.resetChoices();
        this.choice = Choice.S10;
        this.s10 = s10;
    }

    toString(): string {
        if (this.choice == Choice.OMD0) {
            if (this.omd0 != null) {
                return "choice: {omd0: " + this.omd0 + "}";
            } else {
                return "choice is OMD0 but omd0 is null";
            }
        }else if(this.choice == Choice.S1){
            if(this.s1 != null){
                return "choice: {s1: " + this.s1 + "}";
            }else{
                return "choice is s1 but s1 is null";
            }
        }else if(this.choice == Choice.S2){
            if(this.s2 != null){
                return "choice: {s2: " + this.s2 + "}";
            }else{
                return "choice is s2 but s2 is null";
            }
        }else if(this.choice == Choice.S3){
            if(this.s3 != null){
                return "choice: {s3: " + this.s3 + "}";
            }else{
                return "choice is s3 but s3 is null";
            }
        }else if(this.choice == Choice.S4){
            if(this.s4 != null){
                return "choice: {s4: " + this.s4 + "}";
            }else{
                return "choice is s4 but s4 is null";
            }
        }else if(this.choice == Choice.S5){
            if(this.s5 != null){
                return "choice: {s5: " + this.s5 + "}";
            }else{
                return "choice is s5 but s5 is null";
            }
        }else if(this.choice == Choice.S6){
            if(this.s6 != null){
                return "choice: {s6: " + this.s6 + "}";
            }else{
                return "choice is s6 but s6 is null";
            }
        }else if(this.choice == Choice.S7){
            if(this.s7 != null){
                return "choice: {s7: " + this.s7 + "}";
            }else{
                return "choice is s7 but s7 is null";
            }
        }else if(this.choice == Choice.S8){
            if(this.s8 != null){
                return "choice: {s8: " + this.s8 + "}";
            }else{
                return "choice is s8 but s8 is null";
            }
        }else if(this.choice == Choice.S9){
            if(this.s9 != null){
                return "choice: {s9: " + this.s9 + "}";
            }else{
                return "choice is s9 but s9 is null";
            }
        }else if(this.choice == Choice.S10){
            if(this.s10 != null){
                return "choice: {s10: " + this.s10 + "}";
            }else{
                return "choice is s10 but s10 is null";
            }
        } else {
            return "unknown";
        }
    }

}
